/*
 * ReadMixture.cpp
 *
 *  Created on: 7 gru 2013
 *      Author: rkrawczy135
 */

#include "ReadMixture.hpp"
#include "ParseException.hpp"

readmixture::ReadMixture::ReadMixture()
{

}

readmixture::ReadMixture::~ReadMixture()
{

}

//Read and parse mixture from an input file
//fileName- input file name
//howManyPeople (2 or 3) who many people are in the mixture
std::vector<dna::marker> readmixture::ReadMixture::parseMixFromFile(
		std::string fileName, unsigned int howManyPeople)
{
	//2 or 3 people- only options
	if (howManyPeople != 2 && howManyPeople != 3)
	{
		//std::cout<<"INPUTSIZE !\n";
		throw new exc::SizeException();
	}

	std::vector<dna::marker> markers;
	std::vector<std::string> aux;
	std::ifstream infile(fileName.c_str());

	//check file existence
	if (!infile.good())
	{
		//std::cout<<"NO SUCH FILE !\n";
		throw new exc::FOpenException();
	}

	std::string temp;
	//divide input line by line to a vector of strings 	
	while (std::getline(infile, temp))
	{
		aux.push_back(temp);
	}

	for (unsigned int a = 0; a != aux.size(); a++)
	{
		//std::cout<<"String:" << aux[a]<<"\n";
		std::istringstream iss(aux[a]);
		dna::marker m;
		int q = 0;
		std::string sub;
		while (iss >> sub)
		{

			//	std::cout << "Substring: "<< q << " "<< sub << "\n";
			if (sub.size() == 1 && isalpha(sub[0]) && isupper(sub[0]))
			{
				if (std::find(m.begin(), m.end(), sub[0]) == m.end())
				{

					dna::allel a = sub[0];
					m.push_back(a);
					q++;
				}
				else
				{
					throw new exc::RepException();
					//			std::cout<<"Repetition error!\n";

				}
			}
			else
			{
				//		std::cout<<"Non-Letter error!\n";
				throw new exc::NLetterException();

			}
		};
		//std::cout<<"m Size: "<<m.size()<<"\n";
		if (m.size() <= howManyPeople * 2)
		{
			markers.push_back(m);
		}
		else
		{
			//	std::cout<<"Size error !\n";
			throw new exc::SizeException();

		}
	}

	return markers;
}

//Read and parse a single person profile from an input file
//fileName- input file name
dna::profile readmixture::ReadMixture::parseProFromFile(std::string fileName)
{

	dna::profile genotypes;
	std::vector<std::string> aux;
	std::ifstream infile(fileName.c_str());
	std::string temp;

	//check file existence
	if (!infile.good())
	{
		//std::cout<<"NO SUCH FILE !\n";
		throw new exc::FOpenException();
	}

	//divide input line by line to a vector of strings 	
	while (std::getline(infile, temp))
	{
		aux.push_back(temp);
	}

	for (unsigned int a = 0; a != aux.size(); a++)
	{
		//std::cout<<"String:" << aux[a]<<"\n";
		std::istringstream iss(aux[a]);
		dna::marker m;
		int q = 0;
		std::string sub;
		while (iss >> sub)
		{
			//	std::cout << "Substring: "<< q << " "<< sub << "\n";
			if (sub.size() == 1 && isalpha(sub[0]) && isupper(sub[0]))
			{

				dna::allel a = sub[0];
				m.push_back(a);
				q++;

			}
			else
			{
				//		std::cout<<"Non-Letter error!\n";
				throw new exc::NLetterException();

			}
		};
		//std::cout<<"m Size: "<<m.size()<<"\n";
		if (m.size() == 2)
		{
			//std::cout<<m[0];
			//std::cout<<m[1]<<"\n";
			dna::genotype g(m.front(), (*++m.begin()));
			//std::cout<<g.first;
			genotypes.push_back(g);
		}
		else
		{
			//	std::cout<<"Size error !\n";
			throw new exc::SizeException();

		}
	}

	return genotypes;
}

//return if all the alleli in profile are a subset of alleli in markers
bool readmixture::ReadMixture::checkProfileInMixture(
		std::vector<dna::marker> mixture, dna::profile profile)
{
	//different size- false
	if (mixture.size() != profile.size())
		return false;

	//profile allel not in mixture alleli- false
//	for (unsigned int i = 0; i != mixture.size(); i++)
//	{
	size_t i = 0;
	for (dna::profile::iterator profileIterator = profile.begin(); profileIterator != profile.end(); ++profileIterator)
	{

		dna::marker mix = mixture[i++];
		dna::allel pr1 = (profileIterator->first);
		dna::allel pr2 = (profileIterator->second);
		dna::marker::iterator mixtureIterator;

		mixtureIterator = find(mix.begin(), mix.end(), pr1);
		if (mixtureIterator == mix.end())
		{
			return false;
		}
		mixtureIterator = find(mix.begin(), mix.end(), pr2);
		if (mixtureIterator == mix.end())
		{
			return false;
		}
	}
	//other cases- true
	return true;
}

